package com.mt.api.modules.service.impl;


import com.google.common.collect.Lists;
import com.mt.common.response.WebListResponse;
import com.mt.api.modules.domain.BossRole;
import com.mt.api.modules.domain.Menu;
import com.mt.api.modules.domain.RoleMenu;
import com.mt.api.modules.domain.vo.UserRoleMenuVo;
import com.mt.api.modules.manager.IBossRoleManager;
import com.mt.api.modules.manager.IMenuManager;
import com.mt.api.modules.manager.IRoleMenuManager;
import com.mt.api.modules.service.IBossRoleService;
import com.mt.api.util.JwtUserUtils;
import com.mt.common.response.WebResponse;
import com.mt.common.response.WebResponseUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author: plover
 * @Date: 2022-04-30
 * @Description:
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class BossRoleServiceImpl implements IBossRoleService {

    private final IBossRoleManager bossRoleManager;
    private final IRoleMenuManager roleMenuManager;
    private final IMenuManager menuManager;


    @Override
    public WebResponse getRoleMenu() {
        Integer bossId = JwtUserUtils.getJwtUser().getAppBoss().getId();
        List<Menu> menuList = getMenuByBossId(bossId);

        menuList = menuList.stream().filter(menu -> !Objects.equals(menu.getPid(), 0)).collect(Collectors.toList());

        List<UserRoleMenuVo> voList = Lists.newArrayList();
        Map<Integer, List<Menu>> map = menuList.stream().collect(Collectors.groupingBy(Menu::getPid));
        map.forEach((pid, menus) -> {
            Menu menu = menuManager.getById(pid);
            UserRoleMenuVo vo = new UserRoleMenuVo();
            vo.setTitle(menu.getTitle());
            vo.setIcon(menu.getIcon());
            vo.setUrl(menu.getUrl());
            vo.setLinkType(menu.getLinkType());
            vo.setMenuSort(menu.getMenuSort());
            List<UserRoleMenuVo.Children> childrenList = menus.stream().sorted(Comparator.comparing(Menu::getMenuSort)).map(childMenu -> {
                UserRoleMenuVo.Children children = new UserRoleMenuVo.Children();
                children.setTitle(childMenu.getTitle());
                children.setIcon(childMenu.getIcon());
                children.setUrl(childMenu.getUrl());
                children.setLinkType(childMenu.getLinkType());
                children.setMenuSort(childMenu.getMenuSort());
                return children;
            }).collect(Collectors.toList());
            vo.setChildrenList(childrenList);
            voList.add(vo);
        });
        List<UserRoleMenuVo> collect = voList.stream().sorted(Comparator.comparing(UserRoleMenuVo::getMenuSort)).collect(Collectors.toList());
        return WebResponseUtils.successList(collect);
    }

    @Override
    public WebListResponse<UserRoleMenuVo> getRoleCommonMenu() {
        Integer bossId = JwtUserUtils.getJwtUser().getAppBoss().getId();
        List<UserRoleMenuVo> voList = Lists.newArrayList();
        List<Menu> menuList = getMenuByBossId(bossId);
        menuList = menuList.stream().filter(menu -> Objects.equals(menu.getIsCommon(), 1))
                .sorted(Comparator.comparing(Menu::getCommonSort)).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(menuList)) {
            return WebResponseUtils.successListV2(voList);
        }
        voList = menuList.stream().map(menu -> {
            UserRoleMenuVo vo = new UserRoleMenuVo();
            vo.setTitle(menu.getTitle());
            vo.setIcon(menu.getIcon());
            vo.setUrl(menu.getUrl());
            vo.setLinkType(menu.getLinkType());
            vo.setMenuSort(menu.getMenuSort());
            return vo;
        }).collect(Collectors.toList());
        return WebResponseUtils.successListV2(voList);
    }

    private List<Menu> getMenuByBossId(Integer bossId) {
        List<BossRole> bossRoleList = bossRoleManager.getListByBossId(bossId);
        List<Menu> menuList = Lists.newArrayList();
        if (CollectionUtils.isEmpty(bossRoleList)) {
            log.info("getMenuByBossId user role is empty, bossId: {}", bossId);
            return menuList;
        }
        List<Integer> roleIds = bossRoleList.stream().map(BossRole::getRoleId).collect(Collectors.toList());
        if (roleIds.contains(1)) {
            menuList = menuManager.getList();
        } else {
            List<RoleMenu> roleMenuList = roleMenuManager.getByRoleIds(roleIds);
            if (CollectionUtils.isEmpty(roleMenuList)) {
                log.info("getMenuByBossId role menu is empty, bossId: {}, roleIds: {}", bossId, roleIds);
                return menuList;
            }
            List<Integer> menuIds = roleMenuList.stream().map(RoleMenu::getMenuId).collect(Collectors.toList());
            menuList = menuManager.getListByMenuIds(menuIds);
        }
        return menuList;
    }
}
